.set noreorder
.set noat
.globl __start
.section text

__start:
.text
# 运动员目前个数$v0
# a数组内存地址$s0,用以取分数,放分数
# 一轮8个分数放入$t0 ~ $t7
# 一个人的分数总和放入$s1
# 取完所有分数快排
# 初始化运动员个数
# b数组内存基址$s2
# s3,放入运动员阈值
# s4,s5比较大小并大的放入s4,小的放入s5
# s6,s7,t8,t9 掩码

#define swap_if_lt(a,b) \
slt $t8, a   , b    ; \
beq  $t8, $zero, 111f; \
nop                   ; \
xor  b  , b  , a     ; \
xor  a  , a  , b     ; \
xor  b  , b  , a     ; \
111:

//排序后array[0]里是最大数
//该宏会修改t0-t7寄存器
#define bubble_sort_int(array, n) \
ori   $t6, $zero, 0    /* t6 =  i           */ ; \
ori   $t7, $zero, n-1  /* t7 =  n-1         */ ; \
/*for(i=0; i <n-1; i++)                   */ ; \
44: ori   $t5, $zero, 0    /* t5 =  j           */ ; \
addiu $t0, $zero, -1   /*  -1               */ ; \
xor   $t0, $t6, $t0     /*  -i               */ ; \
addiu $t0, $t0,    1   /*  -i+1 = -i        */ ; \
addu  $t4, $t7, $t0     /* t4 =  n-1-i       */ ; \
/*for(j=0; j <n-1-i; j++)                 */ ; \
33: ori   $t0, $zero,  2                           ; \
sll   $t0, $t5, $t0     /*       4*j         */ ; \
addu  $t3, array, $t0  /*      *a[j]        */ ; \
lw    $t1, 0($t3)      /* t1 =  a[j]        */ ; \
lw    $t2, 4($t3)      /* t2 =  a[j+1]      */ ; \
swap_if_lt($t1, $t2)   /* if (t1 < t2) swap */ ; \
sw    $t1, 0($t3)      /* a[j]   = t1       */ ; \
sw    $t2, 4($t3)      /* a[j+1] = t2       */ ; \
addiu $t5, $t5, 1                              ; \
bne   $t5, $t4, 33b                            ; \
nop                                          ; \
addiu $t6, $t6, 1                              ; \
bne   $t6, $t7, 44b                            ; \
nop

//排序后array[0]里是最大数
//该宏会修改t0-t7寄存器
#define bubble_sort_char(array, n) \
ori   $t6, $zero, 0    /* t6 =  i           */ ; \
ori   $t7, $zero, n-1  /* t7 =  n-1         */ ; \
/*for(i=0; i <n; i++)                     */ ; \
22: ori   $t5, $zero, 0    /* t5 =  j           */ ; \
addiu $t0, $zero, -1   /*  -1               */ ; \
xor   $t0, $t6, $t0     /*  -i               */ ; \
addiu $t0, $t0,    1   /*  -i+1 = -i        */ ; \
addu  $t4, $t7, $t0     /* t4 =  n-1-i       */ ; \
/*for(j=0; j <n-i; j++)                   */ ; \
11: addu  $t3, array, $t5  /*      *a[j]        */ ; \
lb    $t1, 0($t3)      /* t1 =  a[j]        */ ; \
lb    $t2, 1($t3)       /* t2 =  a[j+1]      */ ; \
swap_if_lt($t1, $t2)   /* if (t1 < t2) swap */ ; \
sb    $t1, 0($t3)      /* a[j]   = t1       */ ; \
sb    $t2, 1($t3)      /* a[j+1] = t2       */ ; \
addiu $t5, $t5, 1                              ; \
bne   $t5, $t4, 11b                            ; \
nop                                          ; \
addiu $t6, $t6, 1                              ; \
bne   $t6, $t7, 22b                            ; \
nop   

# 从array1读4个数，求平均,值加上s1
# 会修改t0,t1,t2,t3,t4
#define get_ave(array1)\
lb $t0,0(array1);\
lb $t1,1(array1);\
lb $t2,2(array1);\
lb $t3,3(array1);\
addu $t0,$t0,$t1;\
addu $t0,$t0,$t2;\
addu $t0,$t0,$t3;\
srl $t0,$t0,2	;\
addu $s1,$s1,$t0

START:
and $v0,$zero,$zero		# 清空运动员个数
and $s3,$zero,$zero		# 清空运动员阈值
ori $s3,0x0BB8			# 设置运动员阈值
and $a1,$zero,$zero		# 清空轮数阈值
ori $a1,10
and $s0,$zero,$zero		# 清空a数组基址
lui $s0,0x8040			# 设置a数组基址
ori $s0,0x0000			
and $s2,$zero,$zero		# 清空b数组基址
lui $s2,0x8060			# 设置b数组
ori $s2,0x0000

and $s1,$zero,$zero		# 第一次清空分数
and $a0,$zero,$zero		# 第一次清空轮数
LOOP1:					# 运动员循环
and $a0,$zero,$zero
LOOP2:					# 一轮的开始
						# 给8个char数排序
bubble_sort_char($s0,8)
addiu $s0,$s0,2
get_ave($s0)	# 求平均并放入加上$s1,一轮结束
addiu $a0,$a0,1			# 轮数加一
addiu $s0,$s0,6
bne $a0,$a1,LOOP2
nop

# 10轮都结束了,写入
sw $s1,0($s2)
addiu $s2,$s2,4
addiu $v0,$v0,1			# 完成计算1个运动员
bne $v0,$s3,LOOP1		# 计算下一个运动员
and $s1,$zero,$zero		# 清空分数
# 运动员计算结束,排序 
and $s2,$zero,$zero		# 清空b数组基址
lui $s2,0x8060			# 设置b数组
ori $s2,0x0000
bubble_sort_int($s2,3000)
jr $ra
